/**
 * 
 */
package uk.ac.lkl.lpp.ui;

import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

import java.lang.reflect.Constructor;

import java.util.logging.Logger;
import java.util.HashMap;

//import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JTextField;
import javax.swing.border.EtchedBorder;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;

import uk.ac.lkl.common.ui.SlidePanel;
import uk.ac.lkl.common.util.ds.NotifyingList;
import uk.ac.lkl.common.util.ds.event.ListEvent;
import uk.ac.lkl.common.util.ds.event.ListListener;

//import uk.ac.lkl.lpp.dirtyListener;
import uk.ac.lkl.lpp.model.ldo.LearningEntity;

/**
 * @author yish
 *
 */
public final class LEDrawer<L extends LearningEntity> extends SlidePanel implements ListListener {
	private static final long serialVersionUID = 1L;
	private static final Logger logger = Logger.getLogger("uk.ac.lkl.lpp");

    private NotifyingList<L> list;
    private Class<L> entityClass;
    /**
     * panal showing full details of LearningEnteties I'm listing.
     */
    private JPanel entitiesPanel = new JPanel(new GridBagLayout());
    /**
     * name of new entity to add.
     */
    private JTextField  newName        = new JTextField(10);
    private JTextField  newDescription = new JTextField(20);
	private GridBagConstraints c = new GridBagConstraints();
	int gridy = 0;
	HashMap<L, LEPanel> lesMap = new HashMap<L, LEPanel>();
	HashMap<L, EntityNameButton>  lbsMap = new HashMap<L, EntityNameButton>();
	
    

	/**
	 * 
	 */
	public LEDrawer(NotifyingList<L> list, Class<L> entityClass, String title) {
		super (title, null);
		this.list = list;
		this.entityClass =entityClass; 
		list.addListListener(this);
		
		Box b = Box.createHorizontalBox();
		// name of new entity
		//c.gridx =  GridBagConstraints.LINE_START;
		//b.add(new JLabel("name:"));
		//b.add(newName,c);
		
		// description
		//b.add(new JLabel("description:"));
		//b.add(newDescription);
			
		// button to invoke creation of new entity 
		JButton jb = new JButton ("add new..");
		jb.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				createNew();
			}
		});
		b.add(jb,c);
		c.anchor = GridBagConstraints.LINE_START;
		c.gridy = GridBagConstraints.LAST_LINE_END;
		c.fill = GridBagConstraints.HORIZONTAL;
		c.weightx = 1.0;
		entitiesPanel.add(b,c);
		
		c.gridy = 0;
        for (int i = 0; i < list.size(); i++) {
        	addEntity(list.get(i),list);            
        }		
        setPayload(entitiesPanel);
	}
	
	/**
	 * add aim title to the selector, title and description to payload.
	 * map them to ent, so we can remove later.
	 * @param ent
	 * @param list
	 */
	protected void addEntity(L ent, NotifyingList<L> list){
		EntityNameButton enb = new EntityNameButton(ent,7);
        enb.setBorder(new EtchedBorder());	
        lbsMap.put(ent, enb);
        selector.add(enb);
        
        //ent.addChangeListener(new TitleChangeListener(jl,ent));
        c.gridx = 0;
        c.gridy = gridy++;
        //c.gridwidth = 1;
        
        LEPanel lep = new LEPanel(ent,list);
        lesMap.put(ent, lep);
        entitiesPanel.add(lep,c);
		validate();
		this.refresh();
	}
	
	protected void removeEntity(L ent){
		selector.remove(lbsMap.get(ent));
		lbsMap.remove(ent);
		entitiesPanel.remove(lesMap.get(ent));
		lesMap.remove(ent);
		validate();
		this.refresh();
	}
	
	/**
	 * Create a new LearningEntity&lt;L&gt; element.
	 * Add it to the list, and the rest will be handled by the ListChangeEvent. 
	 *
	 */
	protected void createNew(){
		//LearningEntityEditor lee;
		
		L newEnt = null;
		
		
		String name = newName.getText();
		if (name == null || name.length() == 0) name = "New...";
		try {
			Constructor<L> c =entityClass.getConstructor(String.class);
			newEnt = c.newInstance(name);
			newEnt.setDescription(newDescription.getText());
			
		} catch (Exception e) {
			logger.severe("failed to create new "+c+": "+e.toString());
		} 
		
		//This is the new editing option (Uri)
		list.add(newEnt);
		LearningEntityEditor.getEditorDialog(newEnt, getLocation()).setVisible(true);
		

	}
	
	/**
	 * We listen to the LearningEntities List, and update the display 
	 * when it changes. 
	 */
	public void elementAdded(ListEvent e) {
		addEntity((L)e.getElement(), list);
	}

	/**
	 * We listen to the LearningEntities List, and update the display 
	 * when it changes. 
	 */
	public void elementMoved(ListEvent e) {
		// TODO Auto-generated method stub
		
	}

	/**
	 * We listen to the LearningEntities List, and update the display 
	 * when it changes. 
	 */
	public void elementRemoved(ListEvent e) {
		removeEntity((L)e.getElement());
	}


	/**
	 * This class updates the titles on the title bar when the elements change. 
	 * 
	 * @author yish
	 *
	 */
	private class TitleChangeListener implements ChangeListener {
		private final JLabel l;
		private final LearningEntity ent;
		
		TitleChangeListener (JLabel l, LearningEntity ent){
			this.ent = ent;
			this.l = l;
		}
		
    	public void stateChanged(ChangeEvent e){
    		l.setText(ent.getTitle());
    		l.setToolTipText(ent.getDescription());
    		
    	}		
	}
}
